﻿#region Using
#if NUNIT
using System;
using System.Linq.Expressions;
using NMock2.Syntax;
using NUnit.Framework;
using TestClass = NUnit.Framework.TestFixtureAttribute;
using TestMethod = NUnit.Framework.TestAttribute;
using TestInitialize = NUnit.Framework.SetUpAttribute;
using TestCleanup = NUnit.Framework.TearDownAttribute;
using TestContext = System.Object;
#else
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Category = Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute;
#endif

using NMock2;
using NMock2.Matchers;

#endregion

namespace NMock3.Tests
{
	[TestClass]
	public class ClassTests
	{
		private MockFactory _factory = new MockFactory();

		[Test]
		public void VirtualMethodTest()
		{
			Mock<TesterClass> mock = _factory.CreateMock<TesterClass>();

			string expected = "my string";

			mock.Expects.One.Method(m => m.MyMethod()).WillReturn(expected);

			string s = mock.MockObject.MyMethod();

			Assert.AreEqual(expected, s);
		}

		[Test]
		//[Ignore] //Testing class stuff
		public void ToStringTest()
		{
			Mock<TesterClass> mock = _factory.CreateMock<TesterClass>();

			string expected = "my string";

			mock.Expects.One.Method(m => m.ToString()).WillReturn(expected);

			string s = mock.MockObject.ToString();

			Assert.AreEqual(expected, s);
		}

		public class TesterClass
		{
			public virtual string MyMethod()
			{
				return "Me";
			}

			public override string ToString()
			{
				return base.ToString();
			}
		}

	}

	public class Foo<TInterface>
	{
		public IArgumentSyntax Method(Expression<Action<TInterface>> action)
		{
			throw new NotImplementedException();
		}
		public IAutoArgumentSyntax<TResult> Method<TResult>(Expression<Func<TInterface, TResult>> function)
		{
			throw new NotImplementedException();
		}

		public ICommentSyntax MethodWith(Expression<Action<TInterface>> action)
		{
			throw new NotImplementedException();
		}

		public IAutoActionSyntax<TResult> MethodWith<TResult>(Expression<Func<TInterface, TResult>> function)
		{
			throw new NotImplementedException();
		}

		public ICommentSyntax MethodWith<TProperty>(Expression<Func<TInterface, TProperty>> function, TProperty actualValue)
		{
			throw new NotImplementedException();
		}

		public void test1()
		{
			Foo<Bar> bar = new Foo<Bar>();

			bar.Method(b => b.M1());			//action
			bar.Method(b => b.M2(""));			//action
			bar.Method(b => b.M3());			//func
			bar.Method(b => b.M4(""));			//func

			bar.MethodWith(b => b.M1());		//action
			bar.MethodWith(b => b.M2(""));		//action
			bar.MethodWith(b => b.M3());		//func
			bar.MethodWith(b => b.M4(""));		//func

			bar.MethodWith(b => b.M3(), "");
			bar.MethodWith(b => b.M4(""), "");

		}

		interface Bar
		{
			void M1();
			void M2(string s);
			string M3();
			string M4(string s);
		}

	}
}
